package org.mappi.model;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;

import org.mappi.common.util.CommonUtil;
import org.mappi.exception.MappiRunTimeException;

public class ConditionMatrix {

    public static final String CONDITION_MATRIX_DELIMINATOR = ",";

    private static final String DO_NOT_CARE = "*";

    private static final Pattern allowedKeyPattern = Pattern.compile("(true,|false,|\\*,)*(true|false|\\*)",
            Pattern.CASE_INSENSITIVE);
    
    private static final Pattern allowedValuePattern = Pattern.compile("(\\w+,)*(\\w+)",
            Pattern.CASE_INSENSITIVE);

    private Map<String, String> conditionMatrix = new ConcurrentHashMap<String, String>();

    public String put(String key, String value) {
        boolean valid = false;
        if (CommonUtil.notEmptyString(key) && CommonUtil.notEmptyString(value)) {
            valid = allowedKeyPattern.matcher(key).matches() && allowedValuePattern.matcher(value).matches();
        }
        if(!valid) {
            throw new MappiRunTimeException("Invalid key or value " + key + "-" + value);
        }
        return conditionMatrix.put(key, value);
    }

    public String get(String key) {
        String result = conditionMatrix.get(key);
        if (result == null) {
            Set<String> keys = conditionMatrix.keySet();
            for (String internalKey : keys) {
                if (compareKeys(key, internalKey)) {
                    result = conditionMatrix.get(internalKey);
                    break;
                }
            }
        }
        return result;
    }
    
    public int size() {
        return conditionMatrix.size();
    }

    private boolean compareKeys(String target, String internalKey) {
        String[] targetTokens = target.split(CONDITION_MATRIX_DELIMINATOR);
        String[] internalKeyTokens = internalKey.split(CONDITION_MATRIX_DELIMINATOR);
        for (int index = 0; index < targetTokens.length; index++) {
            if (!targetTokens[index].equalsIgnoreCase(internalKeyTokens[index])) {
                if (!internalKeyTokens[index].equals(DO_NOT_CARE)) {
                    return false;
                }
            }
        }
        return true;
    }

}
